package ssm.Service.Impl;

import com.alibaba.fastjson.JSONObject;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ssm.Dao.SurplusDao;
import ssm.Dao.UserDao;
import ssm.Pojo.YzUsers;
import ssm.Service.UserService;
import ssm.Test.Thread1;
import ssm.Tools.EncryptUtil;
import ssm.Tools.Page;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Service
@Transactional
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao ud;
    @Autowired
    private SurplusDao spd;

    @Autowired
    private SqlSessionFactory sqlSessionFactory;

    @Override
    public YzUsers UserLogin(String account, String password) {
        return this.ud.UserLogin(account,password);
    }

    @Override
    public int UserRegister(YzUsers user) {
        this.ud.UserRegister(user);
        return this.spd.InitSurplus(user.getId(),"1.00");
    }

    @Override
    public int isExistUser(String UUID) {
        return this.ud.isExistUser(UUID);
    }

    @Override
    public int isExistUsername(String username) {
        return this.ud.isExistUsername(username);
    }

    @Override
    public int updateUser(YzUsers user) {
        return this.ud.updateUser(user);
    }

    @Override
    public int deleteUser(String user_id) {
        return this.ud.deleteUser(user_id);
    }

    @Override
    public Page<YzUsers> queryAllUsers(Integer pageNum, Integer pageSize) {
        Page<YzUsers> p=null;
        int totalcount=queryTotalUser();
        if(totalcount>0){
            p=new Page<YzUsers>(pageNum,pageSize,totalcount);
            List<YzUsers> list=this.ud.queryAllUsers(p.getIndex(),p.getPageSize());
            p.setList(list);
            return p;
        }
        return null;
    }

    @Override
    public int queryTotalUser() {
        return this.ud.queryTotalUser();
    }

    @Override
    public int BatchInsertUsers(List<Map<String,String>> list,Integer status) {
        Map<String,Object> mvp=new LinkedHashMap<>();
        //设置该批成员的身份类型
        mvp.put("status",status);
        //将List<Map>转化为List<YzUsers>
        List<YzUsers> userlist=new ArrayList<>();
        //存储每个用户的id,当user存在时为其添加账户关联
        List<String> ids=new ArrayList<>();
        YzUsers u=null;
        for(Map<String,String> ul:list){
            u=new YzUsers();
            //填充用户id
            String create_uid="";
            while(true){
                String uuid= UUID.randomUUID().toString().replaceAll("-", "");
                int count=isExistUser( uuid );
                if(count==0){
                    create_uid=uuid;break;
                }
            }
            u.setId(create_uid);
            ids.add(create_uid);
            //填充其余属性
            Iterator<Map.Entry<String,String>> it=ul.entrySet().iterator();
            while(it.hasNext()){
                Map.Entry<String,String> map=it.next();
                if(map.getKey().equals("realname")) u.setRealname(map.getValue());
                if(map.getKey().equals("username")) u.setUsername(map.getValue());
                if(map.getKey().equals("password")) u.setPassword(map.getValue());
                if(map.getKey().equals("qq")) u.setQq(map.getValue());
                if(map.getKey().equals("email")) u.setEmail(map.getValue());
                if(map.getKey().equals("wechat")) u.setWechat(map.getValue());
                if(map.getKey().equals("mobile")) u.setMobile(map.getValue());
                if(map.getKey().equals("address")) u.setAddress(map.getValue());
                if(map.getKey().equals("age")){
                    String ageSTR=map.getValue();
                    if(ageSTR!=null||!ageSTR.equals("")) u.setAge(Integer.parseInt(ageSTR));
                }
                if(map.getKey().equals("sex")) u.setSex(map.getValue());
                if(map.getKey().equals("derive")) u.setDerive(map.getValue());
                if(map.getKey().equals("hobby")) u.setHobby(map.getValue());
                //System.out.println(map.getKey()+"******"+map.getValue());
            }
            userlist.add(u);
        }
        mvp.put("userlist",userlist);
        //批量插入，返回影响行数
        int AffectLine=this.ud.BatchInsertUsers(mvp);
        //为每个用户初始化账户
        for(String id:ids)
            this.spd.InitSurplus(id,"1.00");
        return AffectLine;
    }

    @Override
    public List<YzUsers> BatchFind(List<String> user_ids) {
        return this.ud.BatchFind(user_ids);
    }

    @Override
    public JSONObject ThreadTest(HttpServletRequest request) {
        JSONObject json=new JSONObject();
        String msg="操作码有误";
        int statusCode=-1;
        String type = (request.getParameter("exec_type")==null || request.getParameter("exec_type")=="")?null:request.getParameter("exec_type");
        if(type!=null){
            if("1".equals(type)){
                int affectLine = ud.deleteFrom();
                msg = "操作已执行，已删除"+affectLine+"条数据";
                statusCode = 1;
            }else if("2".equals(type)){
                try{
                    String shuliang=(request.getParameter("count")==null || request.getParameter("count")=="")?null:request.getParameter("count");
                    if(shuliang!=null){
                        int shuLiang = Integer.parseInt(shuliang);
                        // 生成一定数量的用户
                        List<YzUsers> list=new ArrayList<>();
                        YzUsers yu;
                        for(int i=0;i<10000;i++){
                            yu=new YzUsers();
                            yu.setId("u"+Integer.toString(i+1));
                            yu.setRealname("张"+Integer.toString(i));
                            yu.setUsername("zhangsan"+Integer.toString(i));
                            // 使用MD5一次加密后的串存入数据库
                            yu.setPassword(EncryptUtil.getMD5String("123456"));
                            // 允许为空的部分
                            yu.setQq("qq_"+Integer.toString(i+1));
                            yu.setEmail("email_"+Integer.toString(i+1));
                            yu.setWechat("WeChat_"+Integer.toString(i+1));
                            yu.setMobile("mobile_"+Integer.toString(i+1));
                            yu.setAddress("address_"+Integer.toString(i+1));
                            // 年龄 随机数[16,35)
                            yu.setAge((int) Math.random()*(35-16)+16);
                            yu.setSex("男");
                            yu.setDerive("Earth");
                            yu.setHobby("this.爱好");
                            yu.setU_img("https://www.baidu.com/");
                            list.add(yu);
                        }
                        /**
                         * 每个线程插入的数据为1000 <--- 最优效率
                         * 根据数据记录数获得线程总数，但是并发只有10个线程
                         * 根据线程总数对数据进行切割
                         */
                        int mod_=1000;
                        int Thread_size=(list.size()%mod_==0)?(list.size()/mod_):((list.size()/mod_)+1);
                        List<List<YzUsers>> lis = new ArrayList<>(Thread_size);
                        for(int i=0;i<Thread_size;i++){ //[a,b) [0,1000)
                            if(i==(Thread_size-1)){
                                if(list.size()%mod_>0){
                                    lis.add(list.subList(i*mod_, i*mod_+list.size()%1000));
                                }else{
                                    lis.add(list.subList(i*mod_, i*mod_+mod_));
                                }
                            }else{
                                lis.add(list.subList(i*mod_, i*mod_+mod_));
                            }
                        }
                        long startTime = System.currentTimeMillis();
                        Thread[] ts=new Thread[Thread_size];
                        for(int i=0;i<Thread_size;i++){
                            ts[i]=new Thread(new Thread1(lis.get(i),ud,spd,sqlSessionFactory));
                            ts[i].start();
                            ts[i].join();
                        }
                        long endTime = System.currentTimeMillis();
                        String useTime = String.valueOf(endTime - startTime) + "ms";
                        json.put("log", "生成"+shuliang+"条数据所耗费的时间为："+ useTime);
                        msg = "操作已执行，已生成"+shuLiang+"条数据";
                        statusCode = 1;
                    }
                }catch (Exception e){
                    msg= "生成数据数错误，应为数字";
                }
            }
        }
        json.put("statusCode",statusCode);
        json.put("msg",msg);
        return json;
    }
}
